#include "clib_dpdk_loop.h"

/**
 * @brief: Worker线程循环，在该循环中管理定时器，处理网络I/O和其他操作
 * @param arg 指向当前循环的指针（tnet_cycle_t）
 * @return 返回rn_ok表示运行正常结束
 */
int clib_dpdk_loop(void* arg)
{
    uint64_t             prev_dtsc;
    uint64_t             cur_dtsc;
    uint64_t             diff_dtsc;
    uint64_t             tick_dtsc;
    uint16_t             nb_rx = 1024;// 每次处理的数据包数量
    uint16_t             lcore_id  = rte_lcore_id();// 当前核心ID
    uint16_t             socket_id = rte_socket_id();// 当前Socket ID
    clib_cycle_t        *cycle = (clib_cycle_t*)arg;// 指向循环结构体的指针
    clib_lcore_cycle_t  *lcore_cycle = cycle->lcore_cycle[lcore_id];// 指向当前核心运行状况结构体的指针
    clib_netif_node_t   *netif_nodes[cCLIB_NIC_MAX];// 网络接口节点数组
    clib_netif_node_t   *node;// 网络接口节点指针
    int32_t              netif_nodes_n=0;// 网络接口节点数量
    int32_t              work = 0;// 是否有任务正在执行的标志
    int32_t              tx_pkts;// 发送的数据包数量
    
    clib_log_notice("worker lcore %d start,timer hz(%lld)!!!\n",lcore_id,rte_get_timer_hz());

    while(cycle->status)
    {
        work = 0;
        // 根据循环状态执行不同的操作
        if(cycle->status == TNET_WORK_RUNING)
        {
            diff_dtsc = dtsc->cur_dtsc - prev_dtsc;// 计算时间戳差值
            handles  = cycle->handles;
            handle_n = cycle->handle_n;
            for(int i = 0; i < netif_nodes_n;i++)
            {
                node = netif_nodes[i];
                node->tx_pkts = 0;
                node->rx_pkts = rte_eth_rx_burst(node->port_id,node->queue,node->rx_mbuf,nb_rx);
                work += node->rx_pkts;
   
                for(int j = 0; j < handle_n; j++)
                {
                    handle = &handles[j];
                    if(handle->handle)
                    {
                        handle->handle(node,lcore_cycle);
                    }
                    else
                    {
                        tnet_log_notice("handle is NULL,module name is %s \n",cycle->mods[j]->name);
                    }
                }
                
                for(int m = 0; m < node->rx_pkts; m++)
                {
                    rte_pktmbuf_free(node->rx_mbuf[m]);
                }

                node->rx_pkts = 0;
                work += node->tx_pkts;

                tx_pkts = node->tx_pkts;
                uint16_t tx_pkts_n = 0;;
                do{
                    tx_pkts_n += rte_eth_tx_burst(node->port_id,node->queue,&node->tx_mbuf[tx_pkts_n],node->tx_pkts - tx_pkts_n);
                } while (!(tx_pkts_n == tx_pkts));

            }
        }
        else
        {
            usleep(100);
        }
    }

    return rn_ok;
}